// ===================================
// <copyright>
// This file is part of LABSMFController.
//
//    LABSMFController is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    LABSMFController is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with LABSMFController.  If not, see <http://www.gnu.org/licenses/>.
//    Copyright 2011 David Bakker
//
//</copyright>
// <author>David Bakker</author>
// <email>mailto:DavidFBakker@gmail.com</email>
// <created>Saturday, May 07, 2011</created>
// <lastedit>Saturday, May 07, 2011</lastedit>
// ===================================

using System;
using System.Threading;
using LABSMFController.LABS.Classses;
using LABSMFController.LABS.Devices;

namespace LABSMFController.LABS.Services
{
    public class HeaterServiceClass : BeerService
    {
        public static int MAXHeaters = 2;

        private const int RefeshInterval = 250;
        public HeaterDevice[] Heaters;
        private bool HitTemp;
        private Thread _myThread;

        public HeaterServiceClass()
        {
            Location.Setup();
            Heaters = new HeaterDevice[MAXHeaters];
        }

        public override string Description { get; set; }

        //  public static HeaterControl[] HeaterControls;

        public void ResetAllHeaters()
        {
            if (Heaters == null)
                SetupHeaters();

            for (int c = 0; c < MAXHeaters; c++)
            {
                Heaters[c].TurnOff();
            }
        }

        public void SetupHeaters()
        {
            for (int c = 0; c < MAXHeaters; c++)
            {
                switch (c)
                {
                    case 0:

                        Heaters[c] = new HeaterDevice(Location.BK, "Heater BK", Devs.DigitalDevice.BKHeater.PIN1,
                                                      Devs.DigitalDevice.BKHeater.PIN2, Devs.DigitalDevice.BKHeater.LED);

                        break;
                    case 1:
                        Heaters[c] = new HeaterDevice(Location.HLT, "Heater HLT", Devs.DigitalDevice.HLTHeater.PIN1,
                                                      Devs.DigitalDevice.HLTHeater.PIN2,
                                                      Devs.DigitalDevice.HLTHeater.LED);
                                                      

                        break;
                }
            }
        }

        public string GetHeatersClientOutPut()
        {
            string ret = "HEADER:Heaters:" + Heaters[0].Header + ";";
            for (int c = 0; c < MAXHeaters; c++)
            {
                ret = ret + "\r\n" + Heaters[c].GetClientOutPut();
            }
            return ret;
        }

        public override void Configure()
        {
            IsActive = false;
            Description = "Heater Service";
            SetupHeaters();
            ResetAllHeaters();
        }


        public void StartHeater(int heaterLocation, int temperature)
        {
            HitTemp = false;
            Heaters[heaterLocation].HoldTemperature = temperature;
            Heaters[heaterLocation].Run = true;
        }

        public void StopHeater(int heaterLocation)
        {
            HitTemp = false;
            Heaters[heaterLocation].Run = false;
        }


        public override void Stop()
        {
            _myThread.Abort();
            IsActive = false;
        }

        public override void Start()
        {
            BeerProgram.Log(Description + " Starting", LoggingSeverity.Debug);
            IsActive = true;

            _myThread = new Thread(HeaterThread);
            _myThread.Start();
        }

        private void HeaterThread()
        {
            while (true)
            {
                for (int c = 0; c < MAXHeaters; c++)
                {
                    HeaterDevice bc = Heaters[c];
                    int minLEvel = 2;
                    int lo = -1;
                    int ho = -4;
                    try
                    {
                        lo = Convert.ToInt32(Settings.GetSetting("LowSwingTempOffset"));
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        ho = Convert.ToInt32(Settings.GetSetting("HighSwingTempOffset"));
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        minLEvel = Convert.ToInt32(Settings.GetSetting("HeaterMinimumLevel"));
                    }
                    catch (Exception)
                    {
                    }
                    var level = BeerProgram.GetLevel(bc.BubblerLocationID);
                    if (bc.Run && level > minLEvel && bc.HoldTemperature > 0)
                    {
                        if (HitTemp)
                            ho = 0;

                        if (BeerProgram.GetTemp(bc.TempProbeLocationID) >= bc.HoldTemperature + ho)
                        {
                            HitTemp = true;
                            bc.TurnOff();
                        }
                        else if (BeerProgram.GetTemp(bc.TempProbeLocationID) < bc.HoldTemperature + lo)
                        {
                            bc.TurnOn();
                        }
                    }
                    else
                    {
                        if (level <= minLEvel)
                        {
                            BeerProgram.Log("Level is too low to heat at location " + Location.Names[c]);
                        }
                        bc.TurnOff();
                    }
                }


                Thread.Sleep(RefeshInterval);
            }
        }
    }
}